// ========== Copyright Header Begin ==========================================
// 
// OpenSPARC T1 Processor File: Quad.cc
// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// 
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// 
// The above named program is distributed in the hope that it will be 
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// 
// ========== Copyright Header End ============================================
/************************************************************************
**
**  Copyright (C) 2002, Sun Microsystems, Inc.
**
**  Sun considers its source code as an unpublished, proprietary
**  trade secret and it is available only under strict license provisions.
**  This copyright notice is placed here only to protect Sun in the event
**  the source is deemed a published work. Disassembly, decompilation,
**  or other means of reducing the object code to human readable form
**  is prohibited by the license agreement under which this code is
**  provided to the user or company in possession of this copy."
**
*************************************************************************/
#include "Quad.h"
#include <sstream>

using namespace std;
using namespace Riesling;

Quad::Quad()
{
    words_[0] = 0;
    words_[1] = 0;
    words_[2] = 0;
    words_[3] = 0;
}

Quad::Quad( uint64_t lowValue, uint64_t highValue )
{
    words_[0] = (uint32_t ) ( highValue >> 32 );
    words_[1] = (uint32_t )   highValue;

    words_[2] = (uint32_t ) ( lowValue >> 32 );
    words_[3] = (uint32_t )   lowValue;
}

Quad::Quad( uint32_t word0, uint32_t word1, uint32_t word2, uint32_t word3 )
{
    words_[0] = word3;
    words_[1] = word2;
    words_[2] = word1;
    words_[3] = word0;
}

Quad::Quad( const Quad & orig )
{
    words_[0] = orig.words_[0];
    words_[1] = orig.words_[1];
    words_[2] = orig.words_[2];
    words_[3] = orig.words_[3];
}

Quad::~Quad()
{}

const Quad &
Quad::operator=( const Quad & rhs )
{
    words_[0] = rhs.words_[0];
    words_[1] = rhs.words_[1];
    words_[2] = rhs.words_[2];
    words_[3] = rhs.words_[3];

    return *this;
}

bool
Quad::operator==( const Quad & rhs ) const
{
    return ( (words_[0] == rhs.words_[0]) &&
	     (words_[1] == rhs.words_[1]) &&
	     (words_[2] == rhs.words_[2]) &&
	     (words_[3] == rhs.words_[3]) );
}

string
Quad::toString() const
{
    ostringstream os;

    uint64_t   *longPtr;
    uint64_t    values[2];

    longPtr = (uint64_t *) words_;

    values[0] = *longPtr++;
    values[1] = *longPtr++;

    os << "high : 0x" << hex << setw(16) << setfill('0') << values[0];
    os << " ";
    os << "low : 0x" << hex << setw(16) << setfill('0') << values[1];
    os << "\n";


    return os.str();
}

uint32_t
Quad::get( int wordIndex ) const
{
    return words_[ (3 - wordIndex) ];
}

uint64_t
Quad::getHigh() const
{
    uint64_t   lvalue;

    lvalue = *(uint64_t *) &words_[0];

    return lvalue;
}

uint64_t
Quad::getLow() const
{
    uint64_t   lvalue;

    lvalue = *(uint64_t *) &words_[2];

    return lvalue;
}

void
Quad::set( int wordIndex, uint32_t value )
{
    words_[ (3 - wordIndex) ] = value;
}

void
Quad::setHigh( uint64_t highValue )
{
    *(uint64_t *) &words_[0] = highValue;
}

void
Quad::setLow( uint64_t lowValue )
{
    *(uint64_t *) &words_[2] = lowValue;
}
